(function() {
	
	// Load external data
	var states = {};
	states.places = stateExtras.places;
	var stateListOptions = '';
	(function() {
		stateListOptions += '<option><em>- United States -</em></option>'
		for (var i = 0; i < states.places.length; ++i) {
			if (states.places[i].state != 'pr') { // Avoid cases with not enough source data
				stateListOptions += '<option>'+states.places[i].name+'</option>';
			}
		}
		selectEl = '<select id="selector">'+stateListOptions+'</select>';
	})();
	

	var map;
	var selectEl;
	var containerDiv;
	var canvasWidth;
	var currentTransform = null;
	var canvasGraphs = {};
	var markersObj = []
	var lastLinks = '';
	var highlightCircle;
	var hilite = { polys:[] };
	var statesDataReady = false;
	var usDataReady = false;
	var initReady = false;
	var renderReady = false;
	var statesObj = {};
	var currentDay = '08/30'; // default displayed date
	// states data
	var tq = '';
	
	var colorsObj = {
		'Bo': '#0066cc', //EEE600
		'Jm': '#ff0000', // ffcc00, //DC3912
		'Pa': '#009900', //4942cc
		'Bi': '#ff8c00' //4942cc
	};	
	
	
	// format conversion of Doug's data
	externalData = {
		allStates: function(data) {
			tq = data.queries;
			setSourceByDay(tq, '08/30');
			statesDataReady = true;
			if (renderReady && statesDataReady) candidateQueries.addCityMarkers(false, 'Bo', currentDay);
		},
		us: function(data) {
			// add the US case
			var eq = data.queries;
			for (var i = 0, l = eq.length; i < l; ++i) {
				if (!statesObj['us']) {
					statesObj['us'] = {};
				}

				if (eq[i].c == 'o') {
					if (!statesObj['us'].Bo) {
						statesObj['us'].Bo = [];
					}
					statesObj['us'].Bo.push({
						'date': eq[i].d, 
						'hits': eq[i].v});							
				}
				else if (eq[i].c == 'm') {
					if (!statesObj['us'].Jm) {
						statesObj['us'].Jm = [];
					}
					statesObj['us'].Jm.push({
						'date': eq[i].d, 
						'hits': eq[i].v});				
				}
				else if (eq[i].c == 'p') {
					if (!statesObj['us'].Pa) {
						statesObj['us'].Pa = [];
					}
					statesObj['us'].Pa.push({
						'date': eq[i].d, 
						'hits': eq[i].v});				
				}
				else if (eq[i].c == 'b') {
					if (!statesObj['us'].Bi) {
						statesObj['us'].Bi = [];
					}
					statesObj['us'].Bi.push({
						'date': eq[i].d, 
						'hits': eq[i].v});				
				}
			}
			usDataReady = true;
			if (usDataReady && initReady) candidateQueries.renderData();
		}
	};	

	function setSourceByDay(tq, day) {
		for (var i = 0, l = tq.length; i < l; ++i) {		
			if (tq[i].d == day) {
				if (!statesObj[tq[i].s]) {
					statesObj[tq[i].s] = {};
				}
				if (tq[i].c == 'o') {
					statesObj[tq[i].s].Bo = [];
					statesObj[tq[i].s].Bo.push({
						'date': tq[i].d, 
						'hits': tq[i].v});							
				}
				else if (tq[i].c == 'm') {
					statesObj[tq[i].s].Jm = [];
					statesObj[tq[i].s].Jm.push({
						'date': tq[i].d, 
						'hits': tq[i].v});			
				}
				else if (tq[i].c == 'p') {
					statesObj[tq[i].s].Pa = [];
					statesObj[tq[i].s].Pa.push({
						'date': tq[i].d, 
						'hits': tq[i].v});			
				}
				else if (tq[i].c == 'b') {
					statesObj[tq[i].s].Bi = [];
					statesObj[tq[i].s].Bi.push({
						'date': tq[i].d, 
						'hits': tq[i].v});			
				}
			}
		}
	}


	function setSourceByState(tq, state) {
		statesObj[state] = {};
		for (var i = 0, l = tq.length; i < l; ++i) {		
			if (tq[i].s === state) {
				if (!statesObj[tq[i].s]) {
					statesObj[tq[i].s] = {};
				}

				if (tq[i].c == 'o') {
					if (!statesObj[tq[i].s].Bo) {
						statesObj[tq[i].s].Bo = [];
					}
					statesObj[tq[i].s].Bo.push({
						'date': tq[i].d, 
						'hits': tq[i].v});							
				}
				else if (tq[i].c == 'm') {
					if (!statesObj[tq[i].s].Jm) {
						statesObj[tq[i].s].Jm = [];
					}
					statesObj[tq[i].s].Jm.push({
						'date': tq[i].d, 
						'hits': tq[i].v});				
				}
				else if (tq[i].c == 'p') {
					if (!statesObj[tq[i].s].Pa) {
						statesObj[tq[i].s].Pa = [];
					}
					statesObj[tq[i].s].Pa.push({
						'date': tq[i].d, 
						'hits': tq[i].v});				
				}
				else if (tq[i].c == 'b') {
					if (!statesObj[tq[i].s].Bi) {
						statesObj[tq[i].s].Bi = [];
					}
					statesObj[tq[i].s].Bi.push({
						'date': tq[i].d, 
						'hits': tq[i].v});				
				}
			}
		}
	}
				
	// HELPER FUNCTIONS

	// Creates an html element
	var create_ = function(el, opts) {
		if (typeof el === 'string') { // String
			var oEl = document.createElement(el);
		}
		else if (el.tagName || el.item) { // HTML collection [object]
			var oEl = el;
		}
		if (opts.id) oEl.id = opts.id;
		if (opts.elClass) oEl.className = opts.elClass;
		if (opts.text) {
			var text = document.createTextNode(opts.text);
			oEl.appendChild(text);
		}
		if (opts.html) { 
			if (opts.html.splice) { // Array of HTML objects
				for (var i = 0, l = opts.html.length; i < l; i +=1 ) {
					oEl.appendChild(opts.html[i]);
				}
			}
			else {
				oEl.innerHTML = opts.html;			
			}
		}
		return oEl;
	};
	
	// getElementById
	var get_ = function(id) { return document.getElementById(id); }
	
	// toggle visibility
	var toggle_ = function(id) {
		var el = get_(id);
		el.style.display = (el.style.display != 'none' ? 'none' : 'block' );
	};
	
	// date conversion: 02/13 -> February 13th:
	function convertDateToName(date) {
		var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 
									'August', 'September', 'October', 'November', 'Desember'];
		var monthName = months[parseInt(date.match(/(.*)\//)[1], 10) - 1];
		var dayNumber = date.match(/\/(.*)/)[1];
		var dayName = parseInt(dayNumber, 10) + 'th';
		dayName = dayName.replace(/^1th/, '1st');
		dayName = dayName.replace(/^2th/, '2nd');
		dayName = dayName.replace(/^3th/, '3rd');
		return monthName + ' ' + dayName + ':';
	}
	
	// date conversion: Jan 10 2008 -> 01/10
	function convertNameToDate(name) {
		var months = {'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06', 
									'Jul': '07', 'Aug': '08', 'Sep': '09', 'Oct': '10', 'Nov': '11', 'Des': '12'};
		var month = months[name.slice(0,3)];
		var day = name.slice(4,6);
		day = parseInt(day, 10);
		if ((''+day).length == '1') day = '0'+ day;
		return month +"/"+ day;
	}
	
	// MapIconMaker (http://code.google.com/p/gmaps-utility-library/)		
	var MapIconMaker = {};
	MapIconMaker.createMarkerIcon = function(opts) {
	  var width = opts.width || 32;
	  var height = opts.height || 32;
	  var primaryColor = opts.primaryColor || "#bbbbbb";
	  var strokeColor = opts.strokeColor || "#000000";
	  var cornerColor = opts.cornerColor || "#ffffff";

	  var baseUrl = "http://chart.apis.google.com/chart?cht=mm";
	  var iconUrl = baseUrl + "&chs=" + width + "&chco=" + cornerColor.replace("#", "") + "," + 
									primaryColor.replace("#", "") + "," + strokeColor.replace("#", "") + "&ext=.png";
	  var icon = new GIcon(G_DEFAULT_ICON);
	  icon.image = iconUrl;
	  icon.iconSize = new GSize(width, height);
	  icon.shadowSize = new GSize(Math.floor(width*1.6), height);
	  icon.iconAnchor = new GPoint(width/2, height);
	  icon.infoWindowAnchor = new GPoint(width/2, Math.floor(height/12));
	  icon.printImage = iconUrl + "&chof=gif";
	  icon.mozPrintImage = iconUrl + "&chf=bg,s,ECECD8" + "&chof=gif";
	  var iconUrl = baseUrl + "&chs=" + width + "x" + height + "&chco=" + cornerColor.replace("#", "") + "," + 
									primaryColor.replace("#", "") + "," + strokeColor.replace("#", "");
	  icon.transparent = iconUrl + "&chf=a,s,ffffff11&ext=.png";

	  icon.imageMap = [
	      width/2, height,
	      (7/16)*width, (5/8)*height,
	      (5/16)*width, (7/16)*height,
	      (7/32)*width, (5/16)*height,
	      (5/16)*width, (1/8)*height,
	      (1/2)*width, 0,
	      (11/16)*width, (1/8)*height,
	      (25/32)*width, (5/16)*height,
	      (11/16)*width, (7/16)*height,
	      (9/16)*width, (5/8)*height
	  ];
	  for (var i = 0; i < icon.imageMap.length; i++) {
	    icon.imageMap[i] = parseInt(icon.imageMap[i]);
	  }	
	  return icon;
	}
	
	
	// CLASSES
	
	/* SelectList Class */
	//////////////////////
	function selectList() {}
	selectList.prototype = new GControl();
	selectList.prototype.initialize = function(map) {
		var mapBubble = create_('div', {
			id: 'mapBubble',
			html: selectEl
		});
		
		map.getContainer().appendChild(mapBubble);
		return mapBubble;
	}
	selectList.prototype.getDefaultPosition = function() {
	 return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10,8));
	}
	
	
	/* cGraph class */
	//////////////////
	function cGraph() {	}

	// resets this.data and sets the state according to its abbr
	cGraph.prototype.setStateData = function(state, graphs) {
		var stateRef = '';
		this.data = [];
		if (state == 'United States') {
			stateRef = 'us';
		}
		else {
			for (var i = 0; i < states.places.length; ++i) {
				//! check all 50 states
				if (state == states.places[i].name) {
					stateRef = states.places[i].state;
				}
			}
			setSourceByState(tq, stateRef);
		}
		// set data
		for (var i in statesObj[stateRef]) {
			if (statesObj[stateRef].hasOwnProperty(i)) {
				graphs[graphs.length - 1].setGraphData_(i, stateRef);
			}
		}			
	}
	
	// sets this.data for a specific state and fills the missing days with -1 values
	cGraph.prototype.setGraphData_ = function(id, stateRef) {
		var startDate = "03/06"; // it has to match with the first day in the source?
		var finalDate = "10/24"; //! autogenerate that
		var allDates = startDate;
		var lastValue = 0;
		var data = statesObj[stateRef][id];
		this.data.push([]);
		var m = (this.data.length - 1); // %3
		var i = 0;
		for(var n = 0, len = data.length; allDates != finalDate && n < len; n++) {
			// deal with empty days
			while (data[n]['date'] != allDates) {
				if (allDates == finalDate) { break; };
				var aLen = this.data[m].length;
				this.data[m].push({ x: {}, y: {} });
				this.data[m][aLen].x.value = i;
				this.data[m][aLen].y.value = -1;
				this.data[m][aLen].x.label = allDates;
				this.data[m][aLen].y.label = -1;
				this.data[m][aLen].candidate = id;
				allDates = getNextDay(allDates);
				++i;
			}
			if (data[n]['date'] == allDates) {
				var aLen = this.data[m].length;
				this.data[m].push({ x: {}, y: {} });
				this.data[m][aLen].x.value = i;
				this.data[m][aLen].y.value = data[n]['hits'];
				this.data[m][aLen].x.label = data[n]['date'];
				this.data[m][aLen].y.label = data[n]['hits'];
				this.data[m][aLen].candidate = id;
				lastValue = data[n]['hits'];
				allDates = getNextDay(allDates);
				++i;
			}
		}
		function getNextDay(date) {
			var d = new Date();
			var dateSliced = [];
			dateSliced.push(date.slice(0,2));
			dateSliced.push(date.slice(3,5));
			dateSliced.push(d.getFullYear());
			d = new Date(dateSliced.join('/'));
			var time = d.getTime();
			d.setTime(time + 86400000); // next day
			month = (d.getMonth() + 1) + '';
			day = d.getDate() + '';
			if (month.length == 1) month = '0' + month;
			if (day.length == 1) day = '0' + day;
			return month+"/"+day;
		}
	}

	cGraph.prototype.addCanvasGraph = function(canvasEl, outputEl, type, allCandidates) {
		//! refactor
		var spacing = 0;
		var days = 0;
		
		// adjust factors
		if (type == '1w') {
			days = 7;
			spacing = 4.4;
		}
		else if (type == '1m') {
			days = 30;
			spacing = 5.4;
		}
		else if (type == '3m') {
			days = 83;
			spacing = 6;
		}
		else if (type == '6m') {
			days = 159;
			if (days > this.data[0].length) days = this.data[0].length;
			spacing = 6.4;
		}
		var cId = canvasEl.id + 'Bo';
		this.graphId = cId.charAt(cId.length-2) + cId.charAt(cId.length-1); //! remove graphId


		this.width = canvasWidth;
		this.height = 80; 
		this.xLineColor = '#929292'; 
		this.yGridSpacing = 25;
		this.xGridSpacing = spacing * 7;
		this.yGridColor = '#dddddd';
		this.xGridColor = '#dddddd';					
		this.start = this.data[0].length - days;
		this.end = this.data[0].length;
		this.maxY = 200;
		this.xLabel = 'Date';
		this.paddingTop = 0;
		this.paddingRight = 0;
		this.paddingBottom = 0;
		this.paddingLeft = 0;
		this.xLabelSpacing = 0;

		// get the canvas
		this.canvas = canvasEl;
		this.canvas.width = this.width;
		this.canvas.height = this.height;
		this.canvas.style.width = this.width + 'px';
		this.canvas.style.height = this.height + 'px';
		this.ctx = this.canvas.getContext('2d');
									
		this.renderGraph_();
		
		// draw labels
		var label, length, x, y;
		var aLabels = [];
		label = this.data[0][Math.round((0 - this.paddingLeft) / this.scale.horiz) + this.start].x.label;
		aLabels.push('<span style="margin-left: 12px">'+label+'</span>');
		label = this.data[0][Math.round((this.width - this.paddingLeft) / this.scale.horiz) + this.start].x.label;
		aLabels.push('<span style="margin-left: '+(this.width - 41)+'px">'+label+'</span>');
		
		aLabels = aLabels.join('');
		get_('xLabels'+this.graphId).innerHTML = aLabels;
		
		this.lastHoveredDay = '';		
	}
	
	cGraph.prototype.renderGraph_ = function() {
		var ctx = this.ctx;
		ctx.clearRect(0, 0, this.width, this.height);

		// calculateScale:
		this.scale = {};

		this.max = 0;
		this.min = 0;
		for (var m = 0, mLen = this.data.length; m < mLen; m++) {
			for (var n = 0, len = this.data[m].length; n < len; n++) {
				if (this.data[m][n].y.value != -1) {
					if (this.data[m][n].y.value > this.max) {
						this.max = this.data[m][n].y.value;
					}
					if (this.data[m][n].y.value < this.min) {
						this.min = this.data[m][n].y.value;
					}
				}
			}
		}   

		this.max = (this.maxY) ? this.maxY : this.max;
		this.scale.vert = (this.height - this.paddingBottom - this.paddingTop) / (this.max - this.min);
		this.scale.horiz = (this.width - this.paddingLeft - this.paddingRight) / (this.end - this.start - 1);
		this.scale.origin = Math.round(this.height - ((0 - this.min) * this.scale.vert + this.paddingBottom)) - 1;


		// drawGrid:

		// Vertical lines.
		var inc = (this.xGridSpacing < 0) ? this.scale.horiz * 4 : this.xGridSpacing;

		ctx.fillStyle = this.yGridColor;
		for(var n = this.paddingLeft; n < (this.width - this.paddingRight); n += inc) {
			ctx.fillRect(n, 0, 1, this.height - this.paddingBottom);
		}
		ctx.fillRect(this.width - 1, 0, 1, this.height - this.paddingBottom);

		// Horizontal lines.
		inc = (this.yGridSpacing < 0) ? (this.height - this.paddingBottom - this.paddingTop) / 16 : this.yGridSpacing;
		var dataHeight;

		ctx.fillStyle = this.xGridColor;

		for(var n = this.paddingTop; n < (this.height - this.paddingBottom); n += inc) {
			ctx.fillRect(this.paddingLeft, n, this.width - this.paddingLeft - this.paddingRight, 1);
		}			

		
		// drawGraph: drawLine:
		for (var i = 0, l = this.data.length; i < l; ++i) {
			var lastY = 0;
			if (this['check'+this.data[i][0].candidate+this.graphId] !== null) {
				var dataSet = this.data[i];
				ctx.lineWidth = 2;
				//! remove this.color
				ctx.strokeStyle = (this.data.length > 1) ? colorsObj[this.data[i][0].candidate] : this.color;
				ctx.beginPath();
				ctx.moveTo(this.paddingLeft, this.height - ((dataSet[this.start].y.value - this.min) * this.scale.vert) - this.paddingBottom);
				for(var n = this.start, len = dataSet.length; n < this.end && n < len; n++) {
					if(dataSet[n].y.value === null || dataSet[n].y.value == -1) {
						// ctx.stroke();				
						if(dataSet[n + 1]) {
							// ctx.beginPath();
							// ctx.lineTo(dataSet[n + 1].x.value * this.scale.horiz - (this.start * this.scale.horiz) + this.paddingLeft, lastY);
						}
					}
					else {
						ctx.lineTo(dataSet[n].x.value * this.scale.horiz - (this.start * this.scale.horiz) + this.paddingLeft, this.height - ((dataSet[n].y.value - this.min) * this.scale.vert) - this.paddingBottom);
						lastY = this.height - ((dataSet[n].y.value - this.min) * this.scale.vert) - this.paddingBottom;
					}
				}   
				ctx.stroke();				
			}
		}

		// DrawScale:
		// Axes.
		ctx.fillStyle = this.xLineColor;
		ctx.fillRect(this.paddingLeft, this.scale.origin, this.width - this.paddingLeft - this.paddingRight, 1);
	}
	

	cGraph.prototype.attachGraphListeners = function(id, canvasEl, outputEl) {
		// canvasProxy and listeners
		this.parentPosition = { x: YAHOO.util.Dom.getX(this.canvas.parentNode), y: YAHOO.util.Dom.getY(this.canvas.parentNode) };
		this.canvasPosition = { 
			x: YAHOO.util.Dom.getX(this.canvas) - this.parentPosition.x, 
			y: YAHOO.util.Dom.getY(this.canvas) - this.parentPosition.y 
		};		
		this.canvasIndicator = get_('cv-indicator');
		this.canvasIndicator.width = this.width;
		this.canvasIndicator.height = this.height;
		this.canvasIndicator.style.width = this.width + 'px';
		this.canvasIndicator.style.height = this.height + 'px';
		YAHOO.util.Dom.setStyle(this.canvasIndicator, 'z-index', 100);
		YAHOO.util.Dom.setStyle(this.canvasIndicator, 'position', 'absolute');
		YAHOO.util.Dom.setStyle(this.canvasIndicator, 'top', this.canvasPosition.y + 'px');
		YAHOO.util.Dom.setStyle(this.canvasIndicator, 'left', this.canvasPosition.x + 'px');
		
		this.canvasProxy = document.createElement('div');
		this.canvasProxy.id = canvasEl.id +'Bo'+ '-proxy';
		this.canvas.parentNode.appendChild(this.canvasProxy);
		YAHOO.util.Dom.setStyle(this.canvasProxy, 'width', this.width + 'px');
		YAHOO.util.Dom.setStyle(this.canvasProxy, 'height', this.height + 'px');
		YAHOO.util.Dom.setStyle(this.canvasProxy, 'z-index', 200);
		YAHOO.util.Dom.setStyle(this.canvasProxy, 'position', 'absolute');
		YAHOO.util.Dom.setStyle(this.canvasProxy, 'top', this.canvasPosition.y + 'px');
		YAHOO.util.Dom.setStyle(this.canvasProxy, 'left', this.canvasPosition.x + 'px');
		
		var id = this.graphId;
		var ctx = this.ctx;
		var dateId = id;
		var day = '';
		YAHOO.util.Event.on('cv'+id+'-proxy', 'click', function(e) {
			setSourceByDay(tq, this.lastHoveredDay);
			candidateQueries_.addCityMarkers(true, dateId, this.lastHoveredDay);
			currentDay = this.lastHoveredDay;
		}, this, true);
				
		YAHOO.util.Event.on('cv'+id+'-proxy', 'mousemove', function(e) {
			var x = Math.round((e.clientX - this.canvasPosition.x - this.parentPosition.x - this.paddingLeft) / this.scale.horiz) + this.start;
			var args = [];
			
			this.setDashboardValues(x);
			this.drawIndicator(x);			
		}, this, true);
		
		YAHOO.util.Event.on('cv'+id+'-proxy', 'mouseout', function(e) {
			var x = this.getGraphX(currentDay);
			this.setDashboardValues(x);
			this.drawIndicator(x);
		}, this, true);
		
		YAHOO.util.Event.on('outputEl'+id, 'click', function(e) {
			var elTarget = YAHOO.util.Event.getTarget(e);
			if (elTarget.tagName == 'SPAN' && elTarget.parentNode.className != 'active') {
				var links = elTarget.parentNode.parentNode.childNodes;
				for (var i = 0, l = links.length; i < l; i += 1) {
					if (links[i].tagName == 'A' && links[i].className == 'active') {
						links[i].className = '';
						links[i].setAttribute('href', "#");
					}
				}
				elTarget.parentNode.className = 'active';
				elTarget.parentNode.removeAttribute('href');

				//! refactor
				if (elTarget['id'].substring(0,2) == '1w') this.addCanvasGraph(canvasEl, outputEl, '1m', true);	
				if (elTarget['id'].substring(0,2) == '1m') this.addCanvasGraph(canvasEl, outputEl, '3m', true);
				if (elTarget['id'].substring(0,2) == '3m') this.addCanvasGraph(canvasEl, outputEl, '6m', true);	
			}
		}, this, true);
		
		YAHOO.util.Event.on(['checkBo'+id, 'checkJm'+id, 'checkPa'+id, 'checkBi'+id], 'click', function(e) {
			var ckb = YAHOO.util.Event.getTarget(e);
			var candId = ckb.id.slice(5,7);
			get_('row'+candId+this.graphId).style.visibility = (ckb.checked) ? 'visible' : 'hidden';
			this[ckb.id] = (ckb.checked) ? 'active' : null;
			this.renderGraph_();
		}, this, true);
	}
	
	cGraph.prototype.setDashboardValues = function(x) {
		if(x >= this.start) {
			day = this.data[0][x].x.label;
			for(var n = 0, len = this.data.length; n < len; n++) {
				// only render if day changes, i.e. horizontal hover only
				if(this.lastHoveredDay !== day) {
					var c = this.data[n][0].candidate;
					var v = (Math.ceil(this.data[n][x].y.value * 100)) / 100;
					// get_('perc'+c+id).innerHTML = v + '%'; //! change name perc...
					if (v > 80) v = 80;
					if (v < 0) v = 0;
					get_('row'+c+'Bo').style.width = v;

					get_('graphBoDate').innerHTML = convertDateToName(day);
				}
			}
		}
		this.lastHoveredDay = day;
	}
	
	cGraph.prototype.drawIndicator = function(x) {
		// Update the hover info.
		var ctxIndicator = get_('cv-indicator').getContext('2d'); //!
		ctxIndicator.clearRect(0, 0, this.width, this.height);
		// this.renderGraph_();
		if(x >= this.start && x <= this.end) {
			ctxIndicator.strokeStyle = '#bbbbbb';
			ctxIndicator.lineWidth = 2;
			ctxIndicator.beginPath();
			ctxIndicator.moveTo(this.data[0][x].x.value * this.scale.horiz - (this.start * this.scale.horiz) + this.paddingLeft, this.paddingTop + 1);
			ctxIndicator.lineTo(this.data[0][x].x.value * this.scale.horiz - (this.start * this.scale.horiz) + this.paddingLeft, this.height - this.paddingBottom - 1);
			ctxIndicator.stroke();
              
			ctxIndicator.strokeStyle = '#fff';
			ctxIndicator.lineWidth = 1;
			ctxIndicator.fillStyle = '#bbbbbb';

			for(var n = 0, len = this.data.length; n < len; n++) {
				if (this['check'+this.data[n][0].candidate+'Bo'] !== null) { //! change name check....
					ctxIndicator.moveTo(this.data[n][x].x.value * this.scale.horiz - (this.start * this.scale.horiz) + this.paddingLeft, this.height - ((this.data[n][x].y.value - this.min) * this.scale.vert) - this.paddingBottom);
					ctxIndicator.beginPath();
					ctxIndicator.arc(this.data[n][x].x.value * this.scale.horiz - (this.start * this.scale.horiz) + this.paddingLeft, this.height - ((this.data[n][x].y.value - this.min) * this.scale.vert) - this.paddingBottom, 3, 0, 2 * Math.PI, false);
					ctxIndicator.fill();
					ctxIndicator.stroke();
				}
			}
		}	
	}
	
	cGraph.prototype.getGraphX = function(day) {
		for(var n = 0, len = this.data[0].length; n < len; n++) {
			if(this.data[0][n].x.label == day) {
				return n;
			}
		}
		return null;
	}
	/* end of cGraph class */
	
	
	// Main object
	var candidateQueries_ = {
		
		// METHODS SUMMARY
		// init
		// drawHtml : draw sidebar html
		// addCandidate : draw specific candidate thing
			// addCanvasGraph
			// attachGraphListeners
		// addCanvasGraph
		// attachListeners :  sidebar and map listneres
		// attachGraphListeners : graph listeners
		
		
		// METHODS
		init: function() {
			this.graphs = [];
			this.drawHtml();
			this.defaultState = 'United States';
			
			// min map width: 328px
			// min sidebar width: 250px
			// min total width: 578px
			
			//! start set size
			var p = new _IG_Prefs('cqueries');
			var sidebarWidth = 250; //p.getInt('sidebarwidth');
		
			var ms = new _IG_MultiSize();
			var gadgetWidth = ms.getWidth() || window.innerWidth;
			var gadgetHeight = ms.getHeight() || window.innerHeight;
			get_('main').parentNode.style.width = get_('main').style.width = gadgetWidth;
			get_('main').style.height = gadgetHeight;
			
			canvasWidth = 188;
			
			// _IG_AdjustIFrameHeight();
			get_('sidebar_container').style.width = sidebarWidth;				
			var mapwidth = get_('map').style.width = gadgetWidth - sidebarWidth - 4;

			get_('containerCandidates').style.width = '100%';
			var mapheight = get_('containerIssues').style.height = get_('map').style.height = get_('sidebar_container').style.height = gadgetHeight;
			get_('containerCandidates').style.height = gadgetHeight - 15;
			
			if (gadgetWidth < 578) {
				mapheight = mapheight/2;
				mapwidth = gadgetWidth;
				get_('sidebar_container').style.clear = 'left';
				get_('map').style.width = get_('containerIssues').style.width = get_('sidebar_container').style.width = '100%'; 
				
				get_('containerIssues').style.height = get_('containerCandidates').style.height = get_('sidebar_container').style.height = get_('map').style.height = (gadgetHeight - 24) / 2;
				
				canvasWidth = gadgetWidth - 95;
			}
			
			//! end set size
			
			map = new GMap2(document.getElementById('map'));
			map.setCenter(new GLatLng(39.639537564366684,-99.140625), 3);
			map.addControl(new GSmallZoomControl());
			map.addControl(new selectList());

			get_('usTitle').style.display = 'block';
			get_('panelDem').style.display = 'block';
			// get_('panelRep').style.display = 'none';
			
			var loadingEl = create_('div', { id: 'loadingObj', html: '<p>Loading map...</p>'});
			get_('map').appendChild(loadingEl);
			loadingEl.style.top = mapheight/2 - 10;
			loadingEl.style.left = mapwidth/2 - 120;			
			
			initReady = true;
			this.gadgetWidth = gadgetWidth;
			this.canvasWidth = canvasWidth;
			if (initReady && usDataReady) this.renderData();
		},
		
		renderData: function() {
			this.addCandidate('Bo', 'Barack Obama');
			renderReady = true;
			if (renderReady && statesDataReady) this.addCityMarkers(false, 'Bo', currentDay);
			this.attachListeners();
							
			// set bars width
			var x = this.graphs[0].getGraphX(currentDay);
			this.graphs[0].setDashboardValues(x);
			this.graphs[0].drawIndicator(x);

			//! move that
			get_('rowBoBo').style.backgroundColor = colorsObj.Bo;
			get_('rowJmBo').style.backgroundColor = colorsObj.Jm;					
			get_('rowPaBo').style.backgroundColor = colorsObj.Pa;					
			get_('rowBiBo').style.backgroundColor = colorsObj.Bi;								
			
			if (this.gadgetWidth < 578) {
				get_('outputElBo').style.cssFloat = "right";
				get_('outputElBo').style.paddingRight = this.gadgetWidth - this.canvasWidth - 36; // 36 = left position of canvas graph
			}
		},

		drawHtml: function() {
			// party tabs
			var tabsEl = create_('div', {
				id: 'partyTabs',
				html: 	'<ul>'+
						'<li class="active"><a id="demlink" class="link">Candidate Queries</a></li>'+
						// '<li><a id="replink" class="link" href="#">Top Issues</a></li>'+
						'<ul>'
			});			

			var usTitle = create_('div', {
				id: 'usTitle',
				text: 'United States'
			});
			
			
			var subTitleEl = create_('div', { 
				id: 'subTitleEl', 
				html: '<span>Top Candidate Queries</span>'
			});

			// depracated
			var switchView = create_('div', { 
				id: 'switchDiv', 
				html: 	'<a href="#" id="switchAll">View All Combined</a>'+
						'<a href="#" id="switchEach">View Each Candidate</a>'
			});
						
			var instr = create_('div', {
				id: 'instr',
				text: 'Click on the chart to change the date on the map.'
			});
			
			var panelDem = create_('div', { id: 'panelDem' });
			// var panelRep = create_('div', { id: 'panelRep' });			
			var textIntro = create_('p', { id: 'introText', text: 'This map visualizes the amount of Google searches performed from all US states on particular dates'} );
			var mEl = create_('div', { id: 'blankEl', text: '.'});
			var floatedEl = create_('div', { id: 'floatedEl', html: '<br />'});
			var viralLink = create_('p', { id: 'viralLink', html: '<a target="_blank" href="http://maps.google.com/help/maps/elections/">See more maps in the Google Maps Election Gallery</a>'} );
			var trendsEl = create_('h4', { elClass: 'copyTrends', html: 'Relative queries volume: [source: <a target="_blank" href="http://www.google.com/trends?q=Obama%2C+Clinton%2C+McCain&ctab=0&geo=US&geor=all&date=ytd&sort=0">Google Trends</a>]'}) 
			var containerPadding = create_('div', { id: 'containerPadding', html: [textIntro, usTitle, panelDem, floatedEl, viralLink, trendsEl, mEl] });
			var containerCandidates = create_('div', { id: 'containerCandidates', html: [containerPadding] });
			
			// placeholder for future 'Top Issues' section
			var containerIssues = create_('div', { id: 'containerIssues', html: '<div id="usTitle" style="display: block;">California</div><div id="tcolors"><input class="checkbox-issues" type="checkbox" checked="checked" /><span style="color: #fff; background-color: '+colorsObj['Bo']+'" class="legend">Obama</span><input class="checkbox-issues" type="checkbox" checked="checked" /><span style="color: #fff; background-color: '+colorsObj['Hc']+'" class="legend">Clinton</span><input class="checkbox-issues" type="checkbox" checked="checked" /><span style="color: #fff; background-color: '+colorsObj['Jm']+'" class="legend">McCain</span></div>'+
			'<div id="issues-rows"><table><tr><td valign="top" align="right" style="padding: 4px 3px 5px; width: 102px">'+
							'<table width="55" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Bo']+'"/></tr></tbody></table>'+
							'<table width="48" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Hc']+'"/></tr></tbody></table>'+
							'<table width="35" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Jm']+'"/></tr></tbody></table>'+
							'</td><td valign="top" style="padding: 3px 3px 5px"><font size="-1"><b id="trendCity">Economy</b><font color="#393939"></font></font></td>'+
							'<td style="padding-right: 0pt;"> </td>'+
							'</tr></table>'+
							'<table><tr><td valign="top" align="right" style="padding: 4px 3px 5px; width: 102px">'+
							'<table width="79" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Bo']+'"/></tr></tbody></table>'+
							'<table width="23" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Hc']+'"/></tr></tbody></table>'+
							'<table width="35" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Jm']+'"/></tr></tbody></table>'+
							'</td><td valign="top" style="padding: 3px 3px 5px"><font size="-1"><b id="trendCity">Iraq</b><font color="#393939"></font></font></td>'+
							'<td style="padding-right: 0pt;"> </td>'+
							'</tr></table>'+
							'<table><tr><td valign="top" align="right" style="padding: 4px 3px 5px; width: 102px">'+
							'<table width="65" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Bo']+'"/></tr></tbody></table>'+
							'<table width="68" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Hc']+'"/></tr></tbody></table>'+
							'<table width="45" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Jm']+'"/></tr></tbody></table>'+
							'</td><td valign="top" style="padding: 3px 3px 5px"><font size="-1"><b id="trendCity">Health</b><font color="#393939"></font></font></td>'+
							'<td style="padding-right: 0pt;"> </td>'+
							'</tr></table>'+
							'<table><tr><td valign="top" align="right" style="padding: 4px 3px 5px; width: 102px">'+
							'<table width="45" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Bo']+'"/></tr></tbody></table>'+
							'<table width="48" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Hc']+'"/></tr></tbody></table>'+
							'<table width="25" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Jm']+'"/></tr></tbody></table>'+
							'</td><td valign="top" style="padding: 3px 3px 5px"><font size="-1"><b id="trendCity">Taxes</b><font color="#393939"></font></font></td>'+
							'<td style="padding-right: 0pt;"> </td>'+
							'</tr></table>'+
							'<table><tr><td valign="top" align="right" style="padding: 4px 3px 5px; width: 102px">'+
							'<table width="55" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Bo']+'"/></tr></tbody></table>'+
							'<table width="48" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Hc']+'"/></tr></tbody></table>'+
							'<table width="35" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Jm']+'"/></tr></tbody></table>'+
							'</td><td valign="top" style="padding: 3px 3px 5px"><font size="-1"><b id="trendCity">Education</b><font color="#393939"></font></font></td>'+
							'<td style="padding-right: 0pt;"> </td>'+
							'</tr></table>'+																			
							'<table><tr><td valign="top" align="right" style="padding: 4px 3px 5px; width: 102px">'+
							'<table width="65" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Bo']+'"/></tr></tbody></table>'+
							'<table width="38" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Hc']+'"/></tr></tbody></table>'+
							'<table width="15" height="4" cellspacing="1" class="row"><tbody><tr><td bgcolor="'+colorsObj['Jm']+'"/></tr></tbody></table>'+
							'</td><td valign="top" style="padding: 3px 3px 5px"><font size="-1"><b id="trendCity">Energy</b><font color="#393939"></font></font></td>'+
							'<td style="padding-right: 0pt;"> </td>'+
							'</tr></table></div><h4 class="copyTrends">Relative queries volume of the last 12 months: [source: <a href="http://www.google.com/trends?q=Obama%2C+Clinton%2C+McCain&ctab=0&geo=US&geor=all&date=ytd&sort=0">Google Trends</a>]</h4>'});
			containerIssues.style.display = 'none';
			
			// add everything to the main container
			containerDiv = create_(get_('sidebar_container'), {
				html: [tabsEl, containerCandidates, containerIssues]
			});		
		},


		
		addCandidate: function(id, name) {	
			// graph tags
			var outputEl = create_('div', {
				id: 'outputEl'+id,
				elClass: 'outputEl',
				html: '<a href="#"><span id="1w'+id+'">1month</span><span class="border"></span></a>'+
				'<a class="active"><span id="1m'+id+'">3months</span><span class="border"></span></a>'+
				'<a href="#"><span id="3m'+id+'">6months</span><span class="border"></span></a>'
			});
			lastLinks = outputEl.innerHTML;

			// graph info toolbar
			var infoEl = create_('div', {
				id: 'infoEl'+id,
				elClass: 'infoEl'
			});

			infoEl.style.display = 'none';
			
			var yLabels = create_('div', {
				id: 'yLabels'+id,
				elClass: 'yLabels',
				html: '<p>69%</p>'+
				'<p>29%</p>'+
				'<p>9%</p>'
			});
			
			var xLabels = create_('div', {
				id: 'xLabels'+id,
				elClass: 'xLabels',
				html: '<span>10/12</span>'+
				'<span>12/12</span>'+
				'<span>14/12</span>'
			});
			
			var usLink = create_('div', { id: 'usLink', html: '<a href="#">« US graph</a>' });
			
			var graphDate = create_('div', {
				id: 'graph'+id+'Date',
				elClass: 'graphDate',
				text: convertDateToName(currentDay).replace(/:/,'')
			});
						
			var bars = create_('div', {
				id: 'bars'+id,
				elClass: 'bars',
				html: 	'<div id="rowBo'+id+'" class="bar"><span id="percBo'+id+'">10%</span></div>'+
						'<div id="rowJm'+id+'" class="bar"><span id="percJm'+id+'">10%</span></div>' +
												'<div id="rowPa'+id+'" class="bar"><span id="percPa'+id+'">10%</span></div>' +
												'<div id="rowBi'+id+'" class="bar"><span id="percBi'+id+'">10%</span></div>'
			});
			
			// checkboxes list
			var checkboxes = create_('div', {
				id: 'checkboxes'+id,
				elClass: 'checkboxes',
				html: 	'<div><input type="checkbox" id="checkBo'+id+'" checked="checked" /><span>Barack Obama</span></div>'+
						'<div><input type="checkbox" id="checkJm'+id+'" checked="checked" /><span>John McCain</span></div>' +
						'<div><input type="checkbox" id="checkPa'+id+'" checked="checked" /><span>Sarah Palin</span></div>' +
						'<div><input type="checkbox" id="checkBi'+id+'" checked="checked" /><span>Joe Biden</span></div>' 
			});
						
			// candidate graph
			var canvasEl = get_('cv');
			var canvasIndicator = get_('cv-indicator');
			var graphContainer = create_('div', { id: 'graphContainer'+id, elClass: 'graphContainer', html: [outputEl, infoEl, yLabels, canvasEl, canvasIndicator, xLabels, usLink, graphDate, bars, checkboxes] });
			
			// candidate container
			var candidate = create_('div', { 
				id: 'container'+id, 
				elClass: 'container',
				html: [graphContainer]
			});
			get_('panelDem').appendChild(candidate);
			get_('usLink').style.display = 'none';
			
			// render graph
			this.graphs.push(new cGraph());			
			this.graphs[this.graphs.length - 1].setStateData(this.defaultState, this.graphs);
			this.graphs[this.graphs.length - 1].addCanvasGraph(canvasEl, outputEl, '3m', true);
			this.graphs[this.graphs.length - 1].attachGraphListeners(null, canvasEl, outputEl);
		},
		
		addCityMarkers: function(fromGraph, dateId, day) {
			GEvent.clearListeners(map, "click");
			var dateId = dateId || 'Bo';
			var date = get_('graph'+dateId+'Date').innerHTML;
			var scolor = '';
			var range = 0;

			if (currentTransform == null) {
				var restore = '';				
				var maxValues = candidateQueries_.getVolume(day);
				currentTransform = 'sthg';
				map.clearOverlays();
				get_('loadingObj').style.display = 'block';
				get_('loadingObj').innerHTML = '<p>Loading map data for '+date.replace(/:/,'')+'</p>';
				
				var loadingDelay = setInterval(function() {
					var point, newIconi, marker, factor;
					var colors = [colorsObj.Bo, colorsObj.Jm, colorsObj.Pa, colorsObj.Bi];
					for (var i = 0, l = states.places.length; i < l; i+=1) {
						var state = states.places[i];
						point = new GLatLng(state.centroid[1], state.centroid[0]);
						var abbr = state.state;
						var currentState = maxValues[abbr];
						var candidateMsg = '';
						if (state.state != 'pr') { // Avoid state with not enough source data
							if (currentState == undefined || currentState == 'none') { //!
								range = 20;
								scolor = '#cccccc';
								candidateMsg = 'none';
							}
							else {
								range = Math.round((((Math.round(currentState.max/10) * 10)/99) * 20) + 15);
								scolor = colorsObj[currentState.candidate];									
								candidateMsg = currentState.candidate;
							}
						
							newIconi = MapIconMaker.createMarkerIcon({width: range, height: range, primaryColor: scolor, cornerColor: scolor});
							marker = new GMarker(point, {icon: newIconi, title: state.name});
							marker['city'] = state.name;
							marker['candidateMsg'] = candidateMsg;
							markersObj.push(marker);
							map.addOverlay(marker);
						}
					}
					get_('loadingObj').style.display = 'none';
					currentTransform = null;
					clearInterval(loadingDelay);
					map.setCenter(new GLatLng(39.639537564366684,-99.140625), 3);
				}, 1700);
												
				var that = this;
				var clickListener = GEvent.addListener(map, "click", function(o) {
					if (statesDataReady) { //! add failure case
						if (o instanceof GMarker) {
							candidateQueries_.highlightCurrentMarkerNew(o);
							that.graphs[0].setStateData(o.city, that.graphs);
							that.graphs[0].renderGraph_();
							get_('usTitle').innerHTML = o.city;
							get_('usLink').style.display = 'block';					
						}
					}
				}, this, true);
				
			}
		},
		
		getVolume: function(day) {
			//! refactor 
			function getMax(raw) {
				if (raw[0] >= raw[1] && raw[0] >= raw[2] && raw[0] >= raw[3]) {
					return { "candidate": "Bi", "max": raw[0] }
				}
				else if (raw[1] >= raw[0] && raw[1] >= raw[2] && raw[1] >= raw[3]) {
					return { "candidate": "Pa", "max": raw[1] }
				}
				else if (raw[2] >= raw[0] && raw[2] >= raw[1] && raw[2] >= raw[3]) {
					return { "candidate": "Jm", "max": raw[2] }
				}
				else if (raw[3] >= raw[0] && raw[3] >= raw[1] && raw[3] >= raw[2]) {
					return { "candidate": "Bo", "max": raw[3] }
				}
				else return 'none';
			}
			var maxValues = {};
			if (day) {
				// console.log(statesObj)
				for (var i in statesObj) {
					var rawValues = [];					
					// console.log(i)
					for (var j in statesObj[i]) {
						for (var k = 0, l = statesObj[i][j].length; k < l; ++k) {
							if (statesObj[i][j][k].date == day) {
								rawValues.push(statesObj[i][j][k].hits)
							}
						}
						// console.log(rawValues)
						// console.log(maxValues[i])
						if (typeof maxValues[i] === 'undefined' || maxValues[i] === 'none') {
							maxValues[i] = getMax(rawValues)
						}
						// console.log(maxValues)
					}
				}
			}
			return maxValues;
		},
		
		attachListeners: function() {			
			YAHOO.util.Event.on('partyTabs', 'click', function(e) {
				var elTarget = YAHOO.util.Event.getTarget(e);
				if (elTarget.className == 'link' && elTarget.parentNode.className != 'active') {
					if (elTarget.id == 'replink') {
						get_('containerCandidates').style.display = 'none';
						get_('containerIssues').style.display = 'block';
					}
					else {
						get_('containerCandidates').style.display = 'block';
						get_('containerIssues').style.display = 'none';
					}
					var dl = (elTarget.tagName == 'A') ? get_('demlink') : get_('demlink').parentNode;
					var rl = (elTarget.tagName == 'A') ? get_('replink') : get_('replink').parentNode;
					if (dl.getAttribute('href') == "#") {
						dl.removeAttribute('href'); 
						rl.setAttribute('href', '#');
					} 
					else { 
						dl.setAttribute('href', '#');
						rl.removeAttribute('href'); 
					}
					if (elTarget.tagName == 'A') { //! refactor this
						if (dl.parentNode.className == 'active') { 
							dl.parentNode.className = '';
							rl.parentNode.className = 'active';
						} 
						else { 
							dl.parentNode.className = 'active';
							rl.parentNode.className = ''; 
						}
					}
					else {
						if (dl.className == 'active') { 
							dl.className = '';
							rl.className = 'active';
						} 
						else { 
							dl.className = 'active';
							rl.className = ''; 
						}
					}
				}
			});


			YAHOO.util.Event.on('selector', 'change', function(e) {
				if (statesDataReady) { //! add failure case
					var elTarget = YAHOO.util.Event.getTarget(e);
					var selection = elTarget.options[elTarget.selectedIndex].text;
					if (selection == '- United States -') {
						this.resetGraph();
					}
					else {
						for (var i = 0, l = markersObj.length; i < l; i += 1) {
							if (selection === markersObj[i].city) {
								this.highlightCurrentMarkerNew(markersObj[i]);
								this.graphs[0].setStateData(selection, this.graphs);
								this.graphs[0].renderGraph_();
								get_('usTitle').innerHTML = selection;
								get_('usLink').style.display = 'block';
								break;
							}
						}
					}
				}
			}, this, true);							
			
			YAHOO.util.Event.on('usLink', 'click', function(e) {
				YAHOO.util.Event.stopEvent(e);
				this.resetGraph();
			}, this, true);
		},
		
		resetGraph: function() {
			for(var i = 0, l = hilite.polys.length; i < l; ++i) {
				map.removeOverlay(hilite.polys[i]);
			}
			map.closeInfoWindow();
			map.setCenter(new GLatLng(39.639537564366684,-99.140625), 3);
			get_('usTitle').innerHTML = this.defaultState;
			get_('usLink').style.display = 'none';
			this.graphs[0].setStateData(this.defaultState, this.graphs);
			this.graphs[0].renderGraph_();
		},
		
		highlightCurrentMarkerNew: function(marker) {			
			var message = '';
			for(var i = 0, l = hilite.polys.length; i < l; ++i) {
				map.removeOverlay(hilite.polys[i]);
			}
			hilite.polys = [];
			
			var fullName = (marker.candidateMsg == 'Bo') ? 'Obama' : (marker.candidateMsg == 'Jm') ? 'McCain' : (marker.candidateMsg == 'Pa') ? 'Palin' : (marker.candidateMsg == 'Bi') ? 'Biden' : 'none';
			
			if (fullName == 'none') {
				message = '<div id="bubbleMsg">We don\'t have enough data for '+convertDateToName(currentDay).replace(/:/,'')+'. Use the right panel to see '+marker.city+' search trends over time.</div>';
			}
			else {
				message = '<div id="bubbleMsg"><span style="color: #fff; background-color:'+colorsObj[marker.candidateMsg]+'">'+fullName+'</span> has a higher search volume in '+marker.city+' on '+convertDateToName(currentDay).replace(/:/,'')+'. Use the right panel to see '+marker.city+' search trends over time.</div>';				
			}
			marker.openInfoWindowHtml(message, { disableGoogleLinks: true, maxWidth: 200 });
			
			for (var i = 0; i < states.places.length; ++i) {
				if (marker.city == states.places[i].name) {
					var state = states.places[i];
					for(j = 0, l = state.shapes.length; j < l; ++j) {
						var poly = new GPolygon( this.shapeVertices(state.shapes[j]), '#000000"', 1, .8, '#000000"', .2 );
						hilite.polys.push(poly);
						map.addOverlay( poly );
					}
				}
			}
		},
		
		shapeVertices: function(shape) {
			if( ! shape.vertices ) {
				var points = shape.points, n = points.length;
				var vertices = shape.vertices = new Array( n + 1 );
				for(var i = 0; i < n; ++i) { //? 
					var point = points[i];
					vertices[i] = new GLatLng( point[1], point[0] );
				}
				vertices[n] = new GLatLng( points[0][1], points[0][0] );
			}
			return shape.vertices;
		},
		
		highlightCurrentMarker: function(marker) {
			var markerPoint = marker.getPoint();

			var polyPoints = [];

			if (highlightCircle) {
				map.removeOverlay(highlightCircle);
			}

			var mapNormalProj = G_NORMAL_MAP.getProjection();
			var mapZoom = map.getZoom();
			var clickedPixel = mapNormalProj.fromLatLngToPixel(markerPoint, mapZoom);

			var polySmallRadius = 20;

			var polyNumSides = 20;
			var polySideLength = 18;

			for (var a = 0; a < (polyNumSides+1); a++) {
				var aRad = polySideLength*a*(Math.PI/180);
				var polyRadius = polySmallRadius; 
				var pixelX = clickedPixel.x + polyRadius * Math.cos(aRad);
				var pixelY = clickedPixel.y + polyRadius * Math.sin(aRad);
				var polyPixel = new GPoint(pixelX,pixelY);
				var polyPoint = mapNormalProj.fromPixelToLatLng(polyPixel,mapZoom);
				polyPoints.push(polyPoint);
			}
			// Using GPolygon(points,  strokeColor?,  strokeWeight?,  strokeOpacity?,  fillColor?,  fillOpacity?)
			highlightCircle = new GPolygon(polyPoints,"#000000",2,0.0,"#bbbbbb",.5);
			map.addOverlay(highlightCircle);
		}
	};
		
	candidateQueries = candidateQueries_;
})();




YAHOO.util.Event.on(window, 'load', candidateQueries.init, candidateQueries, true);
// _IG_RegisterOnloadHandler(candidateQueries.init());
